// 节点后端方法

package api

import (
    "os"
    "fmt"
    "net"
    "time"
    "strings"

    "tokyo/common"
    "tokyo/core"
)


// 破解密文
func BreakDark(question common.Question)  {
    fmt.Println("开始破解！")

    // 解析题目
    seq := question.Seq
    darkText := question.DarkText
    askTime := question.AskTime

    // 尝试破解
    var tryBright string
    var tryDark string
    breakStart := time.Now()
    breakCount := 0
    for {
        select {
        case v := <- common.SeqChan:
            // 破解失败逻辑
            // 如果序号通道中有本题序号，说明已被抢先
            if v == seq {
                timeCost := time.Since(breakStart)
                fmt.Println("破解失败，已被其他节点抢先")
                fmt.Println("破解次数：", breakCount)
                fmt.Println("破解时间：", timeCost)
                fmt.Println(strings.Repeat("-", 50))
                return
            }
        default:
            // 循环破解1W次，再重新选择
            for {
                tryBright = core.GetRandStr()
                tryDark = core.GetHashCode(tryBright)
                // 破解次数+1
                breakCount += 1

                // 破解成功逻辑
                if (tryDark == darkText) {
                    timeCost := time.Since(breakStart)
                    fmt.Println("破解成功！")
                    fmt.Println("破解明文：", tryBright)
                    fmt.Println("破解密文：", tryDark)
                    fmt.Println("破解次数：", breakCount)
                    fmt.Println("破解时间：", timeCost)

                    // 计算IP
                    hostName, _ := os.Hostname()
                    nslookup, _ := net.LookupHost(hostName)
                    ip := nslookup[0]
                    // 计算当前时间
                    nowStr := time.Now().Format("2006-01-02 15:04:05")

                    // 封装答案
                    var answer common.Answer
                    answer.NodeIp = ip
                    answer.Seq = seq
                    answer.DarkText = darkText
                    answer.AskTime = askTime
                    answer.Answer = tryBright
                    answer.AnswerTime = nowStr

                    // 向系统发送答案
                    PostAnswer(answer)
                    return
                }

                // 达到次数依然没破解成功，重新选择
                if breakCount % 10000 == 0 {
                    break
                }
            }
        }
    }
}


// 判断作者
func IfAuthor(testRes common.TestResult, myIp string)  {
    if myIp == testRes.AuthorIP {
        time.Sleep(time.Duration(800) * time.Millisecond)
        fmt.Println("非常好，我获得了记账权！")
        fmt.Println(strings.Repeat("-", 50))
    } else {
        fmt.Println("题目已经被其他节点抢先作答了")
        // 发送停止作答信号
        go func ()  {
            common.SeqChan <- testRes.Seq
        }()
        fmt.Println("已通知通道停止作答")
    }
}
